package com.dhcc.DRGsHosp.facade.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.jws.WebService;

import org.apache.commons.codec.binary.Base64;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;

import com.alibaba.fastjson.JSONObject;
import com.dhcc.DRGsHosp.application.FileUploadApplication;
import com.dhcc.DRGsHosp.application.ICDApplication;
import com.dhcc.DRGsHosp.application.XPathParseApplication;
import com.dhcc.DRGsHosp.facade.FileUploadFacade;
import com.dhcc.DRGsHosp.facade.MrDataImportService;
import com.dhcc.DRGsHosp.facade.XPathParseFacade;
import com.dhcc.DRGsHosp.facade.XmlStructureFacade;
import com.dhcc.DRGsHosp.infra.util.GlobalData;
import com.dhcc.DRGsHosp.infra.util.StringUtils;
import com.dhcc.DRGsHosp.ws.mrq.FrontPageServiceLocator;
import com.dhcc.DRGsHosp.ws.mrq.FrontPageServiceSoap;

import net.sf.ehcache.CacheManager;

/**
 * @title		:MrDataImportServiceImpl.java
 * @description	:
 * @author		:lileizheng
 * @date		:2016年12月14日
 * @version     :1.0
 * @copyright   :DHCC 2013-2014 
 */
@WebService(endpointInterface="com.dhcc.DRGsHosp.facade.MrDataImportService", serviceName="MrDataImportService",targetNamespace="MrDataImportService")
public class MrDataImportServiceImpl implements MrDataImportService{
	private static final Logger logger = LoggerFactory.getLogger(MrDataImportServiceImpl.class);
	@Autowired
	private XmlStructureFacade xmlStructureFacade;
	
	@Autowired
	private XPathParseApplication xPathParseApplication;
	
	@Autowired
	private FileUploadApplication fileUploadApplication;
	@Autowired
	private FileUploadFacade fileUploadFacade;
	
	@Autowired
	private XPathParseFacade xPathParseFacade;
	
	@Autowired
    private CacheManager cacheManager;
	
	@Autowired
	private ICDApplication icdApplication;
	
	@Override
	public String mrDataImport(String data) {
		String path = this.getClass().getClassLoader().getResource("/").getPath();
        path = path.substring(1, path.indexOf("WEB-INF"));
        File file =new File(path+"xmldata");
		// 如果文件夹不存在则创建
		if (!file.exists() && !file.isDirectory()) {
			file.mkdir();
		}
		File xmltxt=new File(path+"xmldata/xml.txt");    
		if(file.exists()){//如果存在文件就删除    
			xmltxt.delete(); 
		}
		//新建文件
		try {    
	        file.createNewFile();    
	    } catch (IOException e) {    
	        e.printStackTrace();    
	    }
		//把字符串保存到文件中去
		try{
			FileWriter fw = new FileWriter(path+"xmldata/xml.txt", true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(data);
            bw.close();
            fw.close();
        } catch (Exception e) {
        	e.printStackTrace();
    	}
		//String result = beijingdianli(data,paramMap);//北京电力
		String result = parseXmlFile(data);//普通xml串
		//其他格式的数据需要重新编写新的方法
		return result;
	} 
	
	/**  
	 *  beijingdianli.  
	 *  @Description：
	 *  @Author mazhaoyan
	 *  @param data
	 *  @return 
	 *  @Date:2017年9月14日上午11:54:06   
	 */
	private String beijingdianli(String data,Map<String,Object>paramMap) {
		JSONObject mrDataJson = JSONObject.parseObject(data);
		//消息ID
		String messageID = mrDataJson.getJSONObject("Request").getJSONObject("Header").getString("MessageID");
        //患者主索引
		String patPatientID = mrDataJson.getJSONObject("Request").getJSONObject("Body").getJSONObject("DRGsInfoRt").getString("PATPatientID");
		//操作类型
		String operationType = mrDataJson.getJSONObject("Request").getJSONObject("Body").getJSONObject("DRGsInfoRt").getString("OperationType");
		//文档内容 base64 解密
		String documentContent = mrDataJson.getJSONObject("Request").getJSONObject("Body").getJSONObject("DRGsInfoRt").getString("DocumentContent");
		documentContent = new String(Base64.decodeBase64(documentContent.getBytes()));
		System.out.println(documentContent);
		//操作类型为1 表示撤回 执行删除操作
		if("1".equals(operationType))
		{//删除
			String result = removeMedicalRecordById(patPatientID);
			System.out.println(result);
			if("success".equals(result))
			{
				return "{\"Response\":{\"Header\":{\"SourceSystem\":\"DRGs\",\"MessageID\": \""+messageID+"\"},\"Body\":{\"ResultCode\": \"0\",\"ResultContent\": \"成功\"}}}";
			}
			else
			{
				return "{\"Response\":{\"Header\":{\"SourceSystem\":\"DRGs\",\"MessageID\": \""+messageID+"\"},\"Body\":{\"ResultCode\": \"-1\",\"ResultContent\": \""+result+"\"}}}";
			}
		}
		//执行首页数据解析
		paramMap.put("PMAININDEX",patPatientID);//病例
		String result= parseXmlFile(documentContent);
		if("success".equals(result))
		{
			return "{\"Response\":{\"Header\":{\"SourceSystem\":\"DRGs\",\"MessageID\": \""+messageID+"\"},\"Body\":{\"ResultCode\": \"0\",\"ResultContent\": \"成功\"}}}";
		}
		else
		{
			return "{\"Response\":{\"Header\":{\"SourceSystem\":\"DRGs\",\"MessageID\": \""+messageID+"\"},\"Body\":{\"ResultCode\": \"-1\",\"ResultContent\": \""+result+"\"}}}";
		}
	}
	
	/**  
	 *  removeMedicalRecordById.  
	 *  @Description：根据患者主索引删除 病例信息
	 *  @Author mazhaoyan
	 *  @param patPatientID 患者主索引
	 *  @return 
	 *  @Date:2017年9月8日上午8:54:05   
	 */
	private String removeMedicalRecordById(String patPatientID) {
		List<String> idList = new ArrayList<String>();
		idList.add(patPatientID);
		return fileUploadApplication.deleteCaseInfo(idList);
	}
	/**
	 * 
	 * @methodname    :parseXmlFile
	 * @description   : 使用ztree结构解析xml 数据
	 * @param         :
	 * @author        :mazhaoyan
	 * @return        :
	 * @date          :2017年6月13日
	 */
	@SuppressWarnings("unchecked")
	private String parseXmlFile(String data){
    	try {
	    	//读取文件 转换成Document
	    	Document document = DocumentHelper.parseText(data);
	    	//获取根节点元素对象  
			Element root = document.getRootElement();
			InputStream propInputStream = DrawDataFromHisFacadeImpl.class.getResourceAsStream("/nodeconfig.properties");
			Properties properties = new Properties();
			properties.load(propInputStream);
			String repeatNode = properties.getProperty("mr_node_address");
			if(!StringUtils.hasLength(repeatNode)){
				logger.error("REPEAT_NODE is null 请配置REPEAT_NODE");
				return "REPEAT_NODE is null 请配置REPEAT_NODE";
			}
	        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
	        if(xmlStructureFacade==null){
	        	xmlStructureFacade =(XmlStructureFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospFacadeImplMzy170418");
	        }
			Map<String,Object> initMap = xmlStructureFacade.getInitProperty();
	        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
	        if(xPathParseApplication==null){
	        	xPathParseApplication =(XPathParseApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospFacadeImplXPathParseApplicationImplMzy180119");
	        }
			Map<String,Object> xPathMap = xPathParseApplication.getMrXPathMap("xmlFile");
			//获取重复节点
			List<Element> nodeChild = root.selectNodes(repeatNode);
			int allCnt = nodeChild.size();
			if(allCnt==0){
				logger.error("重复路径为 "+ repeatNode+ " 此路径下没有数据");
				return "重复路径为 "+ repeatNode+ " 此路径下没有数据";
			}
			//线程仓库
			Storage storage = new Storage();
			ExecutorService parseMrDataPools = Executors.newFixedThreadPool(10);//解析获取首页数据线程池
			ExecutorService saveMrDataPools = Executors.newFixedThreadPool(10);//首保存首页数据线程池
			for(Element node: nodeChild){
				parseMrDataPools.execute(new ParseMrdataXML(node,storage,initMap,xPathMap));//解析获取首页数据
				saveMrDataPools.execute(new SaveMrData(storage,initMap));//保存首页数据
			}
			parseMrDataPools.shutdown();
			saveMrDataPools.shutdown();
			parseMrDataPools.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
			saveMrDataPools.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
			cacheManager.clearAll();
    	}
    	catch (Exception e) {
			e.printStackTrace();
			return e.getMessage() ;
		}
		return "success";
	}

	/**  
	 *  @Description：
	 *  @Author mazhaoyan  
	 *  @see com.dhcc.DRGsHosp.facade.MrDataImportService#saveBook(java.lang.String)  
	 */
	@Override
	public String saveBook(String data) {
		System.out.println(data);
		return null;
	}
	/**
     * 
     * @ClassName: parseMrdata  
     * @Description ：    解析获取首页数据
     * @Date: 2018年4月3日 下午3:20:17  
     * @Author mazhaoyan 
     * @Version 2.5.0 DHC-DRGs
     */
	public class ParseMrdataXML extends Thread{
		private Element node;
		private Storage storage = null;
		private Map<String,Object> initMap;
		private Map<String,Object> xPathMap;
		
		public ParseMrdataXML(Element node,Storage storage,Map<String,Object> initMap,Map<String,Object> xPathMap){
			this.node = node;
			this.storage = storage;
			this.initMap = initMap;
			this.xPathMap = xPathMap;
		}
		
		public void run() {
	        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
	        if(xPathParseFacade==null){
	        	xPathParseFacade =(XPathParseFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospFacadeImplMzy180128");
	        }
			Map<String, Object> caseMap = xPathParseFacade.parseXmlNode(node,initMap,xPathMap);
			try {
				storage.push(caseMap);//生产
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	    } 
	}
	/**
	 * 
	 * @ClassName: SaveMrData  
	 * @Description ： 保存首页数据
	 * @Date: 2018年4月3日 下午3:21:34  
	 * @Author mazhaoyan 
	 * @Version 2.5.0 DHC-DRGs
	 */
	public class SaveMrData extends Thread{
		private Storage storage = null;
		private Map<String,Object> initMap;
		
		public SaveMrData(Storage storage,Map<String,Object> initMap){
			this.storage = storage;
			this.initMap = initMap;
		}
		public void run(){
			try {
				//消费
				Map<String, Object> caseMap = storage.pop();
				if(caseMap!=null){
			        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
			        if(fileUploadApplication==null){
			        	fileUploadApplication =(FileUploadApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospFileUploadApplicationImplqiaoyilong20190129");
			        }
					String errInfo = fileUploadApplication.saveCaseInfo(caseMap);//保存
					String pMainIndex = caseMap.get("pMainIndex").toString();
					String operIcd = GlobalData.sysConfig.get("OPER_VERSION");
			        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
			        if(icdApplication==null){
			        	icdApplication =(ICDApplication) ContextLoader.getCurrentWebApplicationContext().getBean("icdApplicationImplqiaoyilong20181026");
			        }
					//调用存储过程，更新手术操作
					icdApplication.updateMrIsOper(pMainIndex, operIcd);
					if(StringUtils.hasLength(errInfo)){
						//写入log日志
						logger.error(pMainIndex+" "+errInfo);
					}else{
				        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
				        if(fileUploadFacade==null){
				        	fileUploadFacade =(FileUploadFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospFacadeImpl18");
				        }
						fileUploadFacade.assembleAndGroup(caseMap,initMap);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();	
			}
		}
	}
	/**
	 * 	@Discription：抽取首页数据,定时任务调用转接，以QuartzJob结尾
	 *  @Author QiaoYiLong  
	 *  @Date: 2018年10月26日 9:18:07  
	 *  @param 默认格式为 0_0_pushDate
	 *  cron 0 0 2 * * ? 每天凌晨2点抽取首页结构化数据
	 */
	public void importMrDataByUpdateQuartzJob(String param) {
		importMrDataByUpdate();
	}
	/**
	 *  @Description：首页数据定时抽取
	 *  @Author：liuhongjun 
	 *  @see com.dhcc.DRGsHosp.facade.MedicalRecordFacade#importMrDataByUpdate()
	 */
	@Override
	public void importMrDataByUpdate() {
		Calendar nowCalendar = Calendar.getInstance();
		nowCalendar.add(Calendar.DATE, -1);
		String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(nowCalendar.getTime());
		System.err.println("auto import " + yesterday + " medicalrecord data");
		// 获取webServices路径
		String wsUrl = "";// 抽取编目数据地址
		String hospCode = "";// 医院代码
		String appCode = ""; // 首页版本
		String cfg = GlobalData.sysConfig.get("MR_STRUC");
		if (!cfg.isEmpty()) {
			wsUrl = cfg.split("θ")[0];
			appCode = cfg.split("θ")[1];
			hospCode = cfg.split("θ")[2];
		} else {
			logger.error("请到系统配置菜单配置参数");
			System.out.println("请到系统配置菜单配置参数");
		}
		// 创建客户端
		System.out.println("creating client...");
		FrontPageServiceLocator frontPageServiceLocator = new FrontPageServiceLocator(wsUrl);
		try {
			FrontPageServiceSoap frontPageService = frontPageServiceLocator.getFrontPageServiceSoap();
			System.out.println("client created");
			String admResultXml = frontPageService.getEpisByUpDate(appCode, hospCode, yesterday, yesterday);
			Document document = DocumentHelper.parseText(admResultXml);
			List<Element> admElementList = document.getRootElement().elements();
			for (Element adm : admElementList) {
				//根据主记录获取病案首页详细信息
				String resultXml = frontPageService.getFPInfoByAdm(appCode, hospCode, adm.getTextTrim(), "");
				// 调用方法保存
				mrDataImport(resultXml);
			}

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}
/**
 *  @Description：导入首页数据
 *  @Author：liuhongjun 
 *  @see com.dhcc.DRGsHosp.facade.MrDataImportService#importMrDataFromHIS(java.lang.String, java.lang.String)
 */
	@Override
	public void importMrDataFromHIS(String dateFrom, String dateTo) {
		//获取webServices路径
				String wsUrl = "";//抽取编目数据地址
				String hospCode = "";//医院代码
				String appCode = ""; //首页版本
				String cfg = GlobalData.sysConfig.get("MR_STRUC");
				System.out.println(cfg);
				if(!cfg.isEmpty()) {
					wsUrl = cfg.split("θ")[0];
					appCode = cfg.split("θ")[1];
					hospCode = cfg.split("θ")[2];
				} else {
					logger.error("请到系统配置菜单配置参数");
				}
				System.out.println(wsUrl);
				System.out.println(appCode);
				System.out.println(hospCode);
				
				//创建客户端
				System.out.println("creating client...");
				FrontPageServiceLocator frontPageServiceLocator = new FrontPageServiceLocator(wsUrl);
				
				try {
					FrontPageServiceSoap frontPageService = frontPageServiceLocator.getFrontPageServiceSoap();
					System.out.println("client created");
					String admResultXml = frontPageService.getEpisByDisDate(appCode, hospCode, dateFrom, dateTo);
					Document document = DocumentHelper.parseText(admResultXml);
					List<Element> admElementList = document.getRootElement().elements();
					for (Element adm : admElementList) {
						//根据主记录获取病案首页详细信息
						String resultXml = frontPageService.getFPInfoByAdm(appCode, hospCode, adm.getTextTrim(), "");
						//调用方法保存
						mrDataImport(resultXml);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
	}	
}
